#pragma once
#include "xoms_api_struct.h"

#ifdef __cplusplus
extern "C" {
#endif

	typedef  struct XTPOrderInfo PXTPOrderInfo;
	typedef  struct XTPTradeReport PXTPTradeReport;
	typedef  struct XTPOrderCancelInfo PXTPOrderCancelInfo;
	typedef  XTPQueryOrderRsp PXTPQueryOrderRsp;
	typedef  XTPQueryTradeRsp PXTPQueryTradeRsp;
	typedef  struct XTPQueryStkPositionRsp PXTPQueryStkPositionRsp;
	typedef  struct XTPQueryAssetRsp PXTPQueryAssetRsp;
	typedef  struct XTPOrderInsertInfo PXTPOrderInsertInfo;
	typedef  struct XTPQueryOrderReq PXTPQueryOrderReq;
	typedef  struct XTPQueryTraderReq PXTPQueryTraderReq;


	typedef void(*disconnected_callback)(long long unsigned int session_id, int reason);
	typedef void(*error_callback)(int error_id, char* error_msg);
	typedef void(*order_event_callback)(PXTPOrderInfo *order_info, long long unsigned int session_id, int error_id, char* error_msg);
	typedef void(*trade_event_callback)(PXTPTradeReport *trade_report, long long unsigned int session_id, int error_id, char* error_msg);
	typedef void(*cancel_order_error_callback)(PXTPOrderCancelInfo *cancel_info, long long unsigned int session_id, int error_id, char* error_msg);
	typedef void(*query_order_callback)(PXTPQueryOrderRsp *query_order_rsp, int request_id, int is_last, long long unsigned int session_id, int error_id, char* error_msg);
	typedef void(*query_trade_callback)(PXTPQueryTradeRsp *query_trade_rsp, int request_id, int is_last, long long unsigned int session_id, int error_id, char* error_msg);
	typedef void(*query_position_callback)(PXTPQueryStkPositionRsp *query_position_rsp, int request_id, int is_last, long long unsigned int session_id, int error_id, char* error_msg);
	typedef void(*query_asset_callback)(PXTPQueryAssetRsp *query_asset_rsp, int request_id, int is_last, long long unsigned int session_id, int error_id, char* error_msg);

	typedef struct callback_interface {
			///当客户端的某个连接与交易后台通信连接断开时，该方法被调用。
			///@param reason 错误原因，请与错误代码表对应
			///@param session_id 资金账户对应的session_id，登录时得到
			///@remark 用户主动调用logout导致的断线，不会触发此函数。api不会自动重连，当断线发生时，请用户自行选择后续操作，可以在此函数中调用Login重新登录，并更新session_id，此时用户收到的数据跟断线之前是连续的
			disconnected_callback _disconnected_cb;

			///错误应答
			///@param error_info 当服务器响应发生错误时的具体的错误代码和错误信息,当error_info为空，或者error_info.error_id为0时，表明没有错误
			///@remark 此函数只有在服务器发生错误时才会调用，一般无需用户处理
			error_callback _error_cb;

			///报单通知
			///@param order_info 订单响应具体信息，用户可以通过order_info.order_xtp_id来管理订单，通过GetClientIDByXTPID() == client_id来过滤自己的订单，order_info.qty_left字段在订单为未成交、部成、全成、废单状态时，表示此订单还没有成交的数量，在部撤、全撤状态时，表示此订单被撤的数量。order_info.order_cancel_xtp_id为其所对应的撤单ID，不为0时表示此单被撤成功
			///@param error_info 订单被拒绝或者发生错误时错误代码和错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误
			///@remark 每次订单状态更新时，都会被调用，需要快速返回，否则会堵塞后续消息，当堵塞严重时，会触发断线，在订单未成交、全部成交、全部撤单、部分撤单、已拒绝这些状态时会有响应，对于部分成交的情况，请由订单的成交回报来自行确认。所有登录了此用户的客户端都将收到此用户的订单响应
			order_event_callback _order_event_cb;

			///成交通知
			///@param trade_info 成交回报的具体信息，用户可以通过trade_info.order_xtp_id来管理订单，通过GetClientIDByXTPID() == client_id来过滤自己的订单。对于上交所，exec_id可以唯一标识一笔成交。当发现2笔成交回报拥有相同的exec_id，则可以认为此笔交易自成交了。对于深交所，exec_id是唯一的，暂时无此判断机制。report_index+market字段可以组成唯一标识表示成交回报。
			///@remark 订单有成交发生的时候，会被调用，需要快速返回，否则会堵塞后续消息，当堵塞严重时，会触发断线。所有登录了此用户的客户端都将收到此用户的成交回报。相关订单为部成状态，需要用户通过成交回报的成交数量来确定，OnOrderEvent()不会推送部成状态。
			trade_event_callback _trade_event_cb;

			///撤单出错响应
			///@param cancel_info 撤单具体信息，包括撤单的order_cancel_xtp_id和待撤单的order_xtp_id
			///@param error_info 撤单被拒绝或者发生错误时错误代码和错误信息，需要快速返回，否则会堵塞后续消息，当堵塞严重时，会触发断线，当error_info为空，或者error_info.error_id为0时，表明没有错误
			///@remark 此响应只会在撤单发生错误时被回调
			cancel_order_error_callback _cancel_order_error_cb;

			///请求查询报单响应
			///@param order_info 查询到的一个报单
			///@param error_info 查询报单时发生错误时，返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误
			///@param request_id 此消息响应函数对应的请求ID
			///@param is_last 此消息响应函数是否为request_id这条请求所对应的最后一个响应，当为最后一个的时候为true，如果为false，表示还有其他后续消息响应
			///@remark 由于支持分时段查询，一个查询请求可能对应多个响应，需要快速返回，否则会堵塞后续消息，当堵塞严重时，会触发断线
			query_order_callback _query_order_cb;

			///请求查询成交响应
			///@param trade_info 查询到的一个成交回报
			///@param error_info 查询成交回报发生错误时返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误
			///@param request_id 此消息响应函数对应的请求ID
			///@param is_last 此消息响应函数是否为request_id这条请求所对应的最后一个响应，当为最后一个的时候为true，如果为false，表示还有其他后续消息响应
			///@remark 由于支持分时段查询，一个查询请求可能对应多个响应，需要快速返回，否则会堵塞后续消息，当堵塞严重时，会触发断线
			query_trade_callback _query_trade_cb;

			///请求查询投资者持仓响应
			///@param position 查询到的一只股票的持仓情况
			///@param error_info 查询账户持仓发生错误时返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误
			///@param request_id 此消息响应函数对应的请求ID
			///@param is_last 此消息响应函数是否为request_id这条请求所对应的最后一个响应，当为最后一个的时候为true，如果为false，表示还有其他后续消息响应
			///@remark 由于用户可能持有多个股票，一个查询请求可能对应多个响应，需要快速返回，否则会堵塞后续消息，当堵塞严重时，会触发断线
			query_position_callback _query_position_cb;

			///请求查询资金账户响应，需要快速返回，否则会堵塞后续消息，当堵塞严重时，会触发断线
			///@param asset 查询到的资金账户情况
			///@param error_info 查询资金账户发生错误时返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误
			///@param request_id 此消息响应函数对应的请求ID
			///@param is_last 此消息响应函数是否为request_id这条请求所对应的最后一个响应，当为最后一个的时候为true，如果为false，表示还有其他后续消息响应
			///@remark 需要快速返回，否则会堵塞后续消息，当堵塞严重时，会触发断线
			query_asset_callback _query_asset_cb;

	}callback_interface;

#ifdef WIN32
	#ifdef MYDLL_EXPORTS
		#define MYDLLAPI  extern "C" __declspec(dllexport)
	#else
		#define MYDLLAPI  extern "C" __declspec(dllimport)
	#endif 
#else
	#define MYDLLAPI 
#endif

	///创建交易接口对象;
	MYDLLAPI int create_trader_api(int client_id, char* save_file_path);
	///释放交易接口对象;
	MYDLLAPI void release_trader_api();
	///注册用户自定义的应答接口
	MYDLLAPI int reg_response_cb(callback_interface* response_interface);
	///登陆
	MYDLLAPI int login(char* ip, int port, char* user, char* password);
	///登出
	MYDLLAPI void logout(int session_id);
    ///获取当前交易日
	MYDLLAPI const char* get_trading_day();
    ///订阅公共流
	MYDLLAPI void subscribe_public_topic(int resume_type);
	///设置软件开发版本号
	MYDLLAPI void set_software_version(char* version);
	///设置软件开发Key
	MYDLLAPI  void set_software_key(char* key);
	///设置心跳检测时间间隔，单位为秒
	MYDLLAPI void set_heartbeat_interval(long long unsigned int interval);
    ///报单录入请求
	MYDLLAPI long long unsigned int insert_order(PXTPOrderInsertInfo *order, long long unsigned int session_id);
	///报单操作请求
	MYDLLAPI long long unsigned int cancel_order(long long unsigned int order_xtp_id, long long unsigned int session_id);
    ///根据报单ID请求查询报单
	MYDLLAPI int query_order_by_xtpid(long long unsigned int order_xtp_id, long long unsigned int session_id, int request_id);
	///请求查询报单
	MYDLLAPI int query_orders(PXTPQueryOrderReq *query_param, long long unsigned int session_id, int request_id);
	///根据委托编号请求查询相关成交
	MYDLLAPI int query_trades_by_xtpid (long long unsigned int order_xtp_id, long long unsigned int session_id, int request_id);
	///请求查询已成交
	MYDLLAPI int query_trades(PXTPQueryTraderReq *query_param, long long unsigned int session_id, int request_id);
	///请求查询投资者持仓
	MYDLLAPI int query_position(char *ticker, long long unsigned int session_id, int request_id);
	///请求查询资产
	MYDLLAPI int query_asset(long long unsigned int session_id, int request_id);
#ifdef __cplusplus
}
#endif
